﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Newtonsoft.Json;
using Hardcodet.Wpf.TaskbarNotification;
using System.Drawing;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Linq;

namespace Central_Control
{
    //ip地址和MAC地址数据
    public class IpMacData
    {
        public string IpAddress { get; set; }
        public string MacAddress { get; set; }
        public bool IsOnline { get; set; } // 新增属性来存储计算机状态
    }

    public partial class Window1 : Window
    {
        private UdpClient udpClient;
        private IPEndPoint serverEndPoint;
        public ConcurrentBag<IpMacData> ipAndMacAddress = new ConcurrentBag<IpMacData>();

        private TaskbarIcon notifyIcon;

        private bool isDragging = false;
        private System.Windows.Point startPoint;

        public Window1()
        {
            InitializeComponent();

            // 计算窗口左上角的位置，使其位于屏幕中间
            double screenWidth = SystemParameters.PrimaryScreenWidth;
            double screenHeight = SystemParameters.PrimaryScreenHeight;
            double windowWidth = this.Width;
            double windowHeight = this.Height;

            this.Left = (screenWidth - windowWidth) / 2;
            this.Top = (screenHeight - windowHeight) / 2;


            // 在应用程序启动时加载保存的数据
            LoadSavedData();

            InitializeClient();

            // 创建TaskbarIcon实例
            notifyIcon = new TaskbarIcon();

            // 设置托盘图标的图标
            notifyIcon.Icon = new Icon("Images/Index_Image/logo.ico"); // 请替换成您的图标文件路径

            // 设置托盘图标的提示文本
            notifyIcon.ToolTipText = "videoplayer";

            // 添加托盘图标的右键菜单
            ContextMenu contextMenu = new ContextMenu();

            // 添加打开菜单项
            MenuItem openMenuItem = new MenuItem();
            openMenuItem.Header = "打开";
            openMenuItem.Click += (sender, e) =>
            {
                this.Show();
                this.WindowState = WindowState.Normal;
            };

            // 添加退出菜单项
            MenuItem exitMenuItem = new MenuItem();
            exitMenuItem.Header = "退出";
            exitMenuItem.Click += (sender, e) =>
            {
                this.Close();
            };

            // 将菜单项添加到上下文菜单
            contextMenu.Items.Add(openMenuItem);
            contextMenu.Items.Add(exitMenuItem);

            // 将上下文菜单分配给托盘图标
            notifyIcon.ContextMenu = contextMenu;

            // 添加左键单击事件处理程序以最小化/恢复窗口
            notifyIcon.TrayLeftMouseDown += (sender, e) =>
            {
                if (this.WindowState == WindowState.Minimized)
                {
                    this.Show();
                    this.WindowState = WindowState.Normal;
                }
                else
                {
                    this.WindowState = WindowState.Minimized;
                }
            };

            // 在应用程序退出时清理托盘图标
            this.Closed += (sender, e) =>
            {
                notifyIcon.Dispose();
            };

            // 添加StateChanged事件以隐藏窗口，而不是关闭它
            this.StateChanged += (sender, e) =>
            {
                if (this.WindowState == WindowState.Minimized)
                {
                    this.Hide(); // 隐藏窗口
                }
            };
        }

        #region 网络唤醒所有计算机

        private async void WakeUpComputer_Click(object sender, RoutedEventArgs e)
        {
            await WakeUpAllComputersAsync();
        }

        private async Task WakeUpAllComputersAsync()
        {
            List<Task> wakeUpTasks = new List<Task>();

            foreach (var ipMacData in ipAndMacAddress)
            {
                wakeUpTasks.Add(WakeUpAsync(ipMacData.IpAddress, ipMacData.MacAddress));
            }

            await Task.WhenAll(wakeUpTasks);
        }

        private async Task WakeUpAsync(string ipAddress, string macAddress)
        {
            try
            {
                // 构造唤醒魔术包并发送
                byte[] macBytes = GetMacBytes(macAddress);
                byte[] packet = new byte[17 * 6];

                // 构造魔术包
                for (int i = 0; i < 6; i++)
                {
                    packet[i] = 0xFF;
                }
                for (int i = 1; i <= 16; i++)
                {
                    for (int j = 0; j < 6; j++)
                    {
                        packet[i * 6 + j] = macBytes[j];
                    }
                }

                // 发送魔术包
                UdpClient client = new UdpClient();
                client.Connect(IPAddress.Broadcast, 4000);
                await client.SendAsync(packet, packet.Length);
                client.Close();

                // 在成功发送唤醒消息后，您可以在界面上显示相应的信息或日志
                Debug.WriteLine("已向 " + ipAddress + " 发送唤醒消息");
            }
            catch (Exception ex)
            {
                // 处理发送唤醒消息时的错误
                Debug.WriteLine("发送唤醒消息时出错：" + ex.Message);
            }
        }

        private static byte[] GetMacBytes(string macAddress)
        {
            byte[] bytes = new byte[6];
            string[] hex = macAddress.Split('-');
            if (hex.Length != 6)
            {
                throw new ArgumentException("Invalid MAC address.");
            }
            try
            {
                for (int i = 0; i < 6; i++)
                {
                    bytes[i] = Convert.ToByte(hex[i], 16);
                }
            }
            catch (FormatException)
            {
                throw new ArgumentException("Invalid MAC address.");
            }
            return bytes;
        }

        #endregion

        #region 

        private void LoadSavedData()
        {
            List<IpMacData> loadedData = new List<IpMacData>();
            if (File.Exists("ip_mac_data.json"))
            {
                string json = File.ReadAllText("ip_mac_data.json");
                loadedData = JsonConvert.DeserializeObject<List<IpMacData>>(json);
            }

            ResultListBox.ItemsSource = loadedData;
            foreach (var data in loadedData)
            {
                ipAndMacAddress.Add(data);
            }
        }

        private async void ScanNetworkButton_Click(object sender, RoutedEventArgs e)
        {
            await EnumComputersAsync();
        }

        private async Task EnumComputersAsync()
        {
            try
            {
                await Task.Run(() =>
                {
                    Parallel.For(1, 256, i =>
                    {
                        string ipAddress = "192.168.10." + i.ToString();

                        // 检查IP地址是否已存在于列表中
                        if (!IsIpInList(ipAddress))
                        {
                            string macAddress = GetMacAddress(ipAddress);

                            if (macAddress != "N/A")
                            {
                                Debug.WriteLine("ip:" + ipAddress + "  |  mac:" + macAddress);
                                IpMacData ipMacData = new IpMacData { IpAddress = ipAddress, MacAddress = macAddress };

                                // 添加到数据列表
                               ipAndMacAddress.Add(ipMacData);

                                // 使用Dispatcher更新界面上的ItemsSource
                                System.Windows.Application.Current.Dispatcher.Invoke(() =>
                                {
                                    ResultListBox.ItemsSource =  ipAndMacAddress.ToList();
                                });

                                // 将数据序列化为JSON字符串
                                string jsonData = JsonConvert.SerializeObject( ipAndMacAddress);

                                // 写入JSON数据到文件
                                File.WriteAllText("ip_mac_data.json", jsonData);

                                // 检查计算机在线状态并更新IsOnline属性
                                bool isOnline = CheckComputerOnline(ipAddress);
                                ipMacData.IsOnline = isOnline;

                                // 使用Dispatcher更新界面上的ItemsSource
                                System.Windows.Application.Current.Dispatcher.Invoke(() =>
                                {
                                    ResultListBox.ItemsSource =  ipAndMacAddress.ToList();
                                });
                            }
                        }
                    });
                });

                // 没有新的IP地址，显示提示
                if ( ipAndMacAddress.All(data => !data.IsOnline))
                {
                    System.Windows.MessageBox.Show("已经获取完成，没有新的在线IP地址。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error: " + ex.Message);
            }
        }


        private bool CheckComputerOnline(string ipAddress)
        {
            try
            {
                Ping ping = new Ping();
                PingReply reply = ping.Send(ipAddress);

                if (reply != null && reply.Status == IPStatus.Success)
                {
                    return true; // 计算机在线
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error checking computer online status: " + ex.Message);
            }

            return false; // 计算机不在线
        }


        private bool IsIpInList(string ipAddress)
        {
            return ipAndMacAddress.Any(data => data.IpAddress == ipAddress);
        }

        private string GetMacAddress(string ipAddress)
        {
            try
            {
                IPAddress ip = IPAddress.Parse(ipAddress);
                byte[] macAddr = new byte[6];
                uint macAddrLen = (uint)macAddr.Length;

                int res = SendARP(BitConverter.ToInt32(ip.GetAddressBytes(), 0), 0, macAddr, ref macAddrLen);
                if (res == 0)
                {
                    string macAddress = BitConverter.ToString(macAddr, 0, (int)macAddrLen);
                    return macAddress;
                }
                else
                {
                    return "N/A";
                }
            }
            catch (Exception ex)
            {
                return "N/A";
            }
        }

        private void InitializeClient()
        {
            udpClient = new UdpClient();
            serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1145); // 请将服务器的IP地址替换为实际的IP地址
        }

        private void SendMessageButton_Click(object sender, RoutedEventArgs e)
        {
            // 为列表中的每个IP地址发送"关机"消息
            foreach (var ipMacData in ipAndMacAddress)
            {
                SendMessageToComputer(ipMacData.IpAddress, "关机：30");
            }
        }

        private void SendMessageToComputer(string ipAddress, string message)
        {
            try
            {
                // 创建目标终结点
                IPEndPoint targetEndPoint = new IPEndPoint(IPAddress.Parse(ipAddress), 1145);

                // 将消息转换为字节数组
                byte[] data = Encoding.UTF8.GetBytes(message);

                // 使用UDP客户端发送消息
                udpClient.Send(data, data.Length, targetEndPoint);

                // 在成功发送消息后，您可以在界面上显示相应的信息或日志
                Debug.WriteLine("已向 " + ipAddress + " 发送消息: " + message);
            }
            catch (Exception ex)
            {
                // 处理发送消息时的错误
                Debug.WriteLine("发送消息时出错：" + ex.Message);
            }
        }

        [DllImport("iphlpapi.dll", ExactSpelling = true)]
        public static extern int SendARP(int destIp, int srcIp, byte[] macAddr, ref uint macAddrLen);
        #endregion

        private void MinimizeButton_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }

        private void MaximizeButton_Click(object sender, RoutedEventArgs e)
        {
            if (this.WindowState == WindowState.Maximized)
            {
                this.WindowState = WindowState.Normal;
            }
            else
            {
                this.WindowState = WindowState.Maximized;
            }
        }

        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

    }
}
